/**
	Pulsar engine. Core.
	Virtual file manager implemetation

	Copyright (C) 2013-2014 Dmitry Dolgov

	This program is free software; you can redistribute it and/or modify it under the terms of the
	GNU General Public License as published by the Free Software Foundation; either version 2 of
	the License, or (at your option) any later version.

	This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
	without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
	See the GNU General Public License for more details.
*/

namespace pl
{

/**
	Standard drive class
*/
class Drive : public pl::ListNode<Drive>
{
public:
	virtual ~Drive() {}

	virtual bool isAccepted(const pl::Filepath& fileName) const = 0;

	// Change translated name to full name
	virtual bool handleTrasnlation(pl::Filepath& fileName)
	{
		return false;
	}

	// Apply custom FAT-specific or platform-specific rules
	virtual void applyPlatformRules(pl::Filepath& fileName)
	{
	}

	/// Get total disk space
	virtual pl::FileError getTotalDiskSpace(pl_uint64 &nBytes) const
	{
		return pl::FILE_ERROR_UNSUPPORTED;
	}

	/// Get free disk space
	virtual pl::FileError getFreeDiskSpace(pl_uint64 &nBytes) const
	{
		return pl::FILE_ERROR_UNSUPPORTED;
	}

	/// Rename a file
	virtual pl::FileError renameFile(const pl::Filepath& oldName, const pl::Filepath& newName)
	{
		return pl::FILE_ERROR_UNSUPPORTED;
	}

	/// Remove a file
	virtual pl::FileError deleteFile(const pl::Filepath& fileName)
	{
		return pl::FILE_ERROR_UNSUPPORTED;
	}

	/// Create directory
	virtual pl::FileError makeDir(const pl::Filepath& dirName)
	{
		return pl::FILE_ERROR_UNSUPPORTED;
	}

	/// Remove directory
	virtual pl::FileError deleteDir(const pl::Filepath& dirName)
	{
		return pl::FILE_ERROR_UNSUPPORTED;
	}

	/// Check file existance
	virtual pl::FileError checkFileExist(const pl::Filepath& fileName) = 0;

	/// Get file attributes
	virtual pl::FileError getFileAttrib(const pl::Filepath& fileName, pl_uint32& attrib)
	{
		return pl::FILE_ERROR_UNSUPPORTED;
	}

	/// Set file attributes
	virtual pl::FileError setFileAttrib(const pl::Filepath& fileName, pl_uint32 attrib)
	{
		return pl::FILE_ERROR_UNSUPPORTED;
	}

	/// Get file size
	virtual pl::FileError getFileSize(const pl::Filepath& fileName, pl_int64& size) = 0;

	/// Set new file size
	virtual pl::FileError setFileSize(const pl::Filepath& fileName, pl_int64 size)
	{
		return pl::FILE_ERROR_UNSUPPORTED;
	}

	/// Query creration, modification or accessing date
	virtual pl::FileError getFileDate(const pl::Filepath& fileName, pl::FileDateType type, pl::DateTime& date)
	{
		return pl::FILE_ERROR_UNSUPPORTED;
	}

	///	Set new creration, modification or accessing date
	virtual pl::FileError setFileDate(const pl::Filepath& fileName, pl::FileDateType type, const pl::DateTime& date)
	{
		return pl::FILE_ERROR_UNSUPPORTED;
	}

	/// Get an interface to find files
	virtual pl::FindFile* findFile(const pl::Filepath& mask)
	{
		return NULL;
	}

	/// Open file for reading
	virtual StreamRead* openFileRead(const pl::Filepath& fileName, pl_uint32 shareAndAttrib) = 0;

	/// Open file for writing
	virtual StreamWrite* openFileWrite(const pl::Filepath& fileName, pl_uint32 shareAndAttrib) = 0;

protected:
	/// ctor
	explicit Drive();

};

/**
	File manager imlementation
*/
class FileManagerImpl : public pl::List<Drive>
{
public:
	/// Must me declared in platform-spec file
	static FileManagerImpl* createImpl();

	/// dtor
	virtual ~FileManagerImpl();

	/// Create subdrives and OS-specific drives
	virtual bool createDrives() = 0;

	/// Copy file
	virtual pl::FileError copyFile(const pl::Filepath& oldName, const pl::Filepath& newName, bool bForce)
	{
		return pl::FILE_ERROR_UNSUPPORTED;
	}

	/// Translate relative filepath to full file path
	virtual bool convertToFullPath(pl::Filepath& fileName) = 0;

protected:
	/// List of all registered deviced
	pl::List<Drive> _allDrives;

	/// ctor
	FileManagerImpl();
};

} // namespace pl

//
// End of file 'pulsar_filemanager_impl.h'
//
